<?php

namespace yunj\app\admin\service\route\page;

use yunj\app\admin\enum\auth\AuthType;
use yunj\app\admin\enum\EnableLoginAuth;
use yunj\app\admin\enum\IsSystem;
use yunj\app\admin\enum\route\RequestMethod;
use yunj\app\admin\enum\route\RouteDataType;
use yunj\app\admin\enum\State;
use yunj\app\admin\model\Model;
use yunj\app\admin\service\route\RouteRequestService;
use yunj\app\admin\service\route\RouteService;
use yunj\app\admin\validate\route\RouteValidate;
use yunj\core\builder\YunjForm;

class RouteEditService extends RouteFormService {

    // 编辑类型
    private $type;

    /**
     * 编辑类型对象
     * @var RouteDataType $typeObj
     */
    private $typeObj;

    // 编辑类型对应id
    private $id;

    // 编辑类型对应数据
    private $data;

    public function __construct() {
        // 类型数据
        if (
            ($idParam = request()->param('id')) && strstr($idParam, '_')
            && (list($type, $id) = explode('_', $idParam))
            && $type && $id && RouteDataType::isValue($type)
        ) {
            /** @var RouteDataType $typeObj */
            $typeObj = RouteDataType::byValue($type);
            $data = $typeObj->getModel()->getOwnRowToArray([
                ['id', '=', $id],
                ['state', '<>', State::DELETED],
            ], ['*', 'if(system_key is null,0,1) as is_system']);
            if ($data) {
                $this->type = $type;
                $this->typeObj = $typeObj;
                $this->id = $id;
                $this->data = $data;
            }
        }

        if (!$this->data) {
            throw new \RuntimeException('请求异常，请刷新页面后重试');
        }
    }

    /**
     * @return mixed|string
     */
    public function getType() {
        return $this->type;
    }

    /**
     * @return RouteDataType
     */
    public function getTypeObj(): RouteDataType {
        return $this->typeObj;
    }

    /**
     * @return mixed|string
     */
    public function getId() {
        return $this->id;
    }

    /**
     * @return array|mixed
     */
    public function getData() {
        return $this->data;
    }

    /**
     * 是否为系统数据
     * @return bool
     */
    public function isSystem(): bool {
        return $this->data['is_system'] ?? null === IsSystem::YES;
    }

    public function getBuilder(): YunjForm {
        $args = [
            'field' => function (YunjForm $builder) {
                return $this->getBuilderField($builder);
            },
            'validate' => RouteValidate::class,
            'button' => function ($builder) {
                // 系统配置的路由请求不允许修改
                return $this->isSystem() && $this->type == RouteDataType::REQUEST ? [] : ['reset', 'submit'];
            },
            'load' => function () {
                $data = $this->data;
                // 必要参数格式转换
                if (
                    $this->type == RouteDataType::REQUEST
                    && ($requireParams = $data['require_params'] ?? [])
                    && is_json($requireParams, $requireParamsData, true)
                    && $requireParamsData
                ) {
                    $showRequireParams = [];
                    foreach ($requireParamsData as $k => $v) {
                        $showRequireParams[] = [
                            'key' => $k,
                            'value' => $v,
                        ];
                    }
                }
                $data['require_params'] = $showRequireParams ?? [];
                return $data;
            },
            'submit' => function (YunjForm $builder, array $data) {
                // 触发设置保存前事件
                event('AdminRouteSaveBefore', ['isEdit' => true, 'loadValues' => $this->data, 'data' => $data]);
                try {
                    /** @var Model $model */
                    $model = $data['model'];
                    $model->change($data['dbData']);
                    // 清理缓存
                    RouteRequestService::clearCache();
                    // 路由重置
                    RouteService::reset();
                    return success_json(["reload" => true]);
                } catch (\Throwable $e) {
                    log_exception($e);
                    return error_json('编辑失败');
                }
            }
        ];
        return YF('RouteEditForm', $args);
    }

    // 获取构建器字段配置
    private function getBuilderField(YunjForm $builder): array {
        $field = [];
        switch ($this->type) {
            case RouteDataType::GROUP:
                // 编辑分组
                $field = [
                        'pid' => ['title' => '父分组', 'type' => "dropdownSearch", 'multi' => false, "options" => build_url('yunjAdminRouteDropdownSearchGroupOptions', ['originLocation' => request()->param('originLocation', AuthType::SIDEBAR_MENU)])],
                        'line' => ['type' => 'line', 'title' => '编辑分组']
                    ] + $this->getGroupCommonField();
                break;
            case RouteDataType::ROUTE:
                // 编辑路由
                $field = [
                        'group_id' => ['title' => '父分组', 'type' => "dropdownSearch", 'multi' => false, "options" => build_url('yunjAdminRouteDropdownSearchGroupOptions', ['originLocation' => request()->param('originLocation', AuthType::SIDEBAR_MENU)])],
                        'line' => ['type' => 'line', 'title' => '编辑路由'],
                    ] + $this->getRouteCommonField();
                break;
            case RouteDataType::REQUEST:
                // 编辑路由请求
                $field = [
                        'route_id' => ['title' => '父路由', 'verify' => 'require', 'type' => "dropdownSearch", 'multi' => false, "options" => build_url('yunjAdminRouteDropdownSearchRouteOptions', ['originLocation' => request()->param('originLocation', AuthType::SIDEBAR_MENU)])],
                        'line' => ['type' => 'line', 'title' => '编辑路由请求'],
                    ] + $this->getRequestCommonField();
                break;
        }

        // 是否为系统配置
        if ($this->isSystem()) {
            if (in_array($this->type, [RouteDataType::GROUP, RouteDataType::ROUTE])) {
                // 系统配置的分组和路由允许调整自定义中间件
                array_insert($field, [
                    'tips' => [
                        'type' => 'txt',
                        'desc' => "温馨提示：系统" . $this->typeObj->getTitle() . "仅允许对自定义中间件进行编辑！",
                        'color' => '#FF5722',
                    ]
                ]);
                foreach ($field as $k => &$v) {
                    if ($k != 'middleware') {
                        $v['readonly'] = true;
                    }
                }
            } else {
                // 系统配置的路由请求不允许修改
                array_insert($field, [
                    'tips' => [
                        'type' => 'txt',
                        'desc' => "温馨提示：系统" . $this->typeObj->getTitle() . "不允许编辑！",
                        'color' => '#FF5722',
                    ]
                ]);
                foreach ($field as $k => &$v) {
                    $v['readonly'] = true;
                }
            }
        } else {
            // 非系统配置不能选择系统配置的分组、路由、路由请求
            $field[$this->typeObj->getTablePidKey()]['desc'] = '系统配置数据已屏蔽';
        }
        // 设置栅格布局
        foreach ($field as &$v) {
            $v['grid'] = [12, "6 l3 r3", "6 l3 r3"];
        }
        return $field;
    }

}